// 基础类型
// number boolean string symbol null undefined
// 对象类型 {} or object ,[] or Array,function,Class类型
const msg: string = "hello ts";
const num: string = "123";
const msg1: string = `${msg} ${num}`;
console.log(msg1);
// boolean
const bool: boolean = false;
// object
const obj: object = {};
const obj1: {} = {};
// 必传
const obj2: { num: number; msg: string } = { num: 0, msg: "22" };
// 可选
const obj3: { num?: number; msg: string } = { msg: "333" };

// array
// 字面量
const arr: [] = [];
const arr2: string[] = [];
const arr5: (string | number)[] = [];
// 构造函数
const arr3: Array<string> = [];
const arr4: Array<string | number> = [];

// function
function add(arg1: number, arg2: number): number {
  return arg1 + arg2;
}
const result = add(1, 2);

const add2 = (arr1: number, arr2: number): number => arr1 + arr2;
const result2 = add2(1, 2);

// 匿名函数
const add3: (arg1: number, arg2: number) => number = (arg1, arg2) =>
  arg1 + arg2;

const result3 = add3(2, 3);

// 函数重载
function handlerData(num: string): string[];
function handlerData(num: number): string;
function handlerData(num: any): any {
  if (typeof num === "string") {
    return num.split("");
  } else {
    return num.toString().split("").join();
  }
}
// handlerData(false); error
// handlerData("111");
handlerData(123);
// 箭头函数 函数重载 error

// 元组 固定类型
const arr10: [string, string, number] = ["1", "2", 3];
// 枚举 常量 性别：男 女
enum Sex {
  Male = 0,
  Female = 1,
}
enum Direction {
  Down,
  Up,
  Left,
  Right,
}

// interface 接口与接口使用extends
interface PublicPoint {
  x: string;
  y: string;
}
interface Point extends PublicPoint {
  z: string;
}

interface PublicPoint2 {
  d: string;
}

interface Point2 extends PublicPoint, PublicPoint2 {}

// 函数定义
interface Func {
  (num1: number, num2: number): number;
}

const addFunc: Func = (arg1, arg2) => arg1 + arg2;

// 索引类型
interface Role {
  [id: number]: string;
}
const role: Role = ["superMan", "woman"];
// console.log(role.length); 使用索引类型不具备array原型上的方法
const role1: Role = {
  0: "super",
  1: "super2",
};
// 绕开多余属性检查

interface MyType {
  color: string;
  //   [prop: string]: any; // 索引签名(推荐)
}

// const addType = (mytype: MyType) => {
//     return `${mytype.color}`;
//   };
const addType = ({ color }: MyType) => {
  return `${color}`;
};
// 类型断言方式 处理报错
addType({ color: "red", type: "color" } as MyType);
// 索引签名
// addType({ color: "red", type: "color" });

// 类型兼容（不推荐）
const opt = { color: "red", type: "color" };
addType(opt);

// Class类
class Person {
  // public - 公共的
  //   protected - 允许在类内及继承的子类中使用
  //   private - 只能在类中使用
  private name = "walk"; // 如果没有加类型默认为public
  getName() {
    return this.name;
  }
}

// 类继承 extends 类与类
class PersonOne extends Person {
  constructor() {
    super();
  }
}
// 定义类接口 implements
interface PersonInterface {
  type: string;
}
// 写法一 接口与类
class PersonTwo implements PersonInterface {
  constructor(public type: string) {}
}
// 写法二 接口与类
class PersonThree implements PersonInterface {
  public type;
  constructor(type: string) {
    this.type = type;
  }
}

// 泛型 基础
function I<T>(arr: [T], arg: T): T[] {
  arr.push(arg);
  return arr;
}
const cusI = I<string>(["1"], "123");
// 泛型 + 元组
const swap = <T, U>(tulp: [T, U]): [U, T] => {
  return [tulp[1], tulp[0]];
};
const res = swap<string, number>(["1", 0]);
res[0].toFixed();
res[1].indexOf("123");
